using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Diagnostics.Contracts;
using System.Collections.ObjectModel;
using System.Collections.Specialized;
using Konst3d.Efficiency;
using Konst3d.Efficiency.Suite;

namespace PEM
{
	internal partial class MilestonesViewModel: ViewModelBase
	{
		#region Types

		internal delegate void EventHandler(ViewModelBase sender);

		public enum SortingType
		{
			Title,
			Date
		}

		#endregion // Types

		#region Events

		public event EventHandler SuiteOpened;
		public event EventHandler SuiteClosed;
		public event EventHandler SuiteCreated;
		public event EventHandler SuiteDeleted;
		public event EventHandler MilestoneSelected;

		#endregion // Events

		#region Properties

		public ObservableList2<IMilestone> Milestones
		{
			get;
			private set;
		}

		public SortingType Sorting
		{
			get
			{
				return _sorting;
			}
			set
			{
				if (_sorting != value)
				{
					_sorting = value;
					UpdateMilestonesList();
				}
			}
		}

		public SortingDirection SortingDirection
		{
			get
			{
				return _sortingDirection;
			}
			set
			{
				if (value != _sortingDirection)
				{
					_sortingDirection = value;
					UpdateMilestonesList();
				}
			}
		}

		public IMilestone Selected
		{
			get
			{
				return _selected;
			}
			set
			{
				_selected = value;

				if (MilestoneSelected != null)
				{
					MilestoneSelected(this);
				}

				NotifyPropertyChanged("Selected");
			}
		}

		public CommandsCollection Commands
		{
			get;
			private set;
		}

		public IEfficiencySuite Suite
		{
			get
			{
				return _parentModel.Suite;
			}
		}

		#endregion // Properties

		#region Constructor

		public MilestonesViewModel(Window parentWindow, MainWindowViewModel parentModel)
		{
			Contract.Requires(parentWindow != null);
			Contract.Requires(parentModel  != null);

			_parentWindow = parentWindow;
			_parentModel = parentModel;

			_parentModel.SuiteOpened += OnSuiteOpened;
			_parentModel.SuiteClosed += OnSuiteClosed;
			_parentModel.SuiteCreated += OnSuiteCreated;
			_parentModel.SuiteDeleted += OnSuiteDeleted;

			_comparers.Add(SortingType.Title, (IMilestone x, IMilestone y) => {
				return _sortingDirection == SortingDirection.Ascending ? String.Compare(x.Title, y.Title) : String.Compare(y.Title, x.Title);
			});
			_comparers.Add(SortingType.Date, (IMilestone x, IMilestone y) => {
				return _sortingDirection == SortingDirection.Ascending ? DateTime.Compare(x.Date, y.Date) : DateTime.Compare(y.Date, x.Date);
			});

			Milestones = new ObservableList2<IMilestone>();
			Commands = new CommandsCollection(this);

			_createEditMilestoneDlg = new CreateEditMilestoneDialog();
		}

		#endregion // Constructor

		#region Overriden Methods

		protected override void DisposeManaged()
		{
			base.DisposeManaged();

			_createEditMilestoneDlg.Close();
			_createEditMilestoneDlg = null;

			_parentModel.SuiteOpened -= OnSuiteOpened;
			_parentModel.SuiteClosed -= OnSuiteClosed;
			_parentModel.SuiteCreated -= OnSuiteCreated;
			_parentModel.SuiteDeleted -= OnSuiteDeleted;
			_parentModel = null;
		}

		#endregion // Overriden Methods

		#region Event Handlers

		private void OnSuiteOpened(MainWindowViewModel sender)
		{
			UpdateMilestonesList();

			if (SuiteOpened != null)
			{
				SuiteOpened(this);
			}
		}

		private void OnSuiteClosed(MainWindowViewModel sender)
		{
			UpdateMilestonesList();

			if (SuiteClosed != null)
			{
				SuiteClosed(this);
			}
		}

		private void OnSuiteCreated(MainWindowViewModel sender)
		{
			UpdateMilestonesList();

			if (SuiteCreated != null)
			{
				SuiteCreated(this);
			}
		}

		private void OnSuiteDeleted(MainWindowViewModel sender)
		{
			UpdateMilestonesList();

			if (SuiteDeleted != null)
			{
				SuiteDeleted(this);
			}
		}

		#endregion // Event Handlers

		#region Private Methods

		private void UpdateMilestonesList()
		{
			Milestones.BeginUpdate();
			Milestones.Clear();

			if (Suite != null)
			{
				foreach (var milestone in Suite.Milestones)
				{
					Milestones.Add(milestone);
				}

				Milestones.Sort(_comparers[_sorting]);
			}

			Milestones.EndUpdate();
		}

		#endregion // Private Methods

		#region Fields

		private Window _parentWindow;
		private MainWindowViewModel _parentModel;
		private IMilestone _selected;
		private SortingType _sorting;
		private SortingDirection _sortingDirection;
		private Dictionary<SortingType, Comparison<IMilestone>> _comparers = new Dictionary<SortingType, Comparison<IMilestone>>();
		private CreateEditMilestoneDialog _createEditMilestoneDlg;

		#endregion // Fields
	}
}
